<template>
  <div class="add-visitor">
      <Modal :mask-closable="false" :width="800" :closable="false" :value="isShowModal" :title="title">
            <Row :guttle="40">
                <Col :span="isShowPhoto ? 16 : 24">
                    <Form
                        ref="form"
                        :model="formData"
                        :rules="formRules"
                        label-position="right"
                        :label-width="100"
                        :show-message="false">

                        <FormItem :label="baseMaterial.names[index]" :prop="key" v-for="(key, index) in baseMaterial.keys" :key="key" >
                            <!-- 证件类型 -->
                            <Select v-model="formData[key]" v-if="key === 'identity_type'" @on-change="typeChange" :disabled="isDisable[key]">
                                <Option v-for="item in certificates_type" :value="item.id" :key="item.id">{{ item.name }}</Option>
                            </Select>

                            <!-- 表单数据 -->
                            <Input v-model.trim="formData[key]" :type="['to_visit_address', 'visit_description'].includes(key) ? 'textarea' : 'text'" :disabled="isDisable[key]" v-else :placeholder="`${(key ==='to_visit_address' || key === 'visit_description') ? '140字符内' : ''}`"></Input>
                        </FormItem>

                        <FormItem label="授权开门时段">
                            <Row>
                                <!-- 开始时间 -->
                                <Col span="10">
                                     <DatePicker type="datetime" placeholder="开始时间" v-model="visit_start_time" style="width: 100%" :disabled="!isShowPhoto"></DatePicker>
                                </Col>

                                <Col span="2" class="center">-</Col>

                                <!-- 结束时间 -->
                                <Col span="10">
                                    <DatePicker type="datetime" placeholder="结束时间" v-model="visit_end_time" style="width: 100%" :disabled="!isShowPhoto"></DatePicker>
                                </Col>
                            </Row>
                        </FormItem>

                        <div v-if="isShowPhoto" :class="['authorize', {'loadSpin' : isLoading}]">
                            <Spin v-if="isLoading"></Spin>

                            <FormItem label="授权门禁" v-else>
                                <CheckboxGroup v-model="device_ids">
                                    <Row v-if="publicDevice.length">
                                        <Col span="6">
                                            <p style="float: right;padding-right: 10px">小区大门门禁:</p>
                                        </Col>

                                        <Col span="18" style="text-align:center; display: flex;flex-wrap: wrap">
                                            <Checkbox :label="device.id" :key="index" v-for="(device, index) in publicDevice">{{device.description === '' ? '门禁' : device.description }}</Checkbox>
                                        </Col>
                                    </Row>

                                    <Row v-if="privateDevice.length">
                                        <Col span="6">
                                            <p style="float: right;padding-right: 10px">单元门门禁:</p>
                                        </Col>

                                        <Col span="18" style="text-align:center; display: flex;flex-wrap: wrap">
                                            <Checkbox :label="device.id" :key="index" v-for="(device, index) in privateDevice">{{device.description === '' ? '门禁' : device.description }}</Checkbox>
                                        </Col>
                                    </Row>
                                </CheckboxGroup>
                            </FormItem>
                        </div>
                    </Form>
                </Col>

                <!-- 照片 -->
                <Col span="8">
                    <takePhoto v-model="face_file_id" :isClearPreviewImg="isClearPreviewImg" v-if="isShowPhoto"></takePhoto>
                </Col>
            </Row>

        <div slot="footer">
            <Button type="ghost" size="large" @click="cancel"> {{status === 1 ? '确定' : '取消'}}</Button>
            <Button type="primary" size="large" @click="ok" v-if="isShowbtn">确定</Button>
        </div>
      </Modal>
  </div>
</template>

<script>
import validate from '@/libs/validate.js'
import takePhoto from './take-photo'
import dayjs from 'dayjs'
import { http, api } from '@/libs/http'
import { certificates } from '@/libs/const'
import debounce from 'lodash/debounce'
export default {
  data () {
    return {
      formData: {}, // 表单数据
      formRules: {}, // 表单规则
      isDisable: {}, // 表单是否禁止编辑
      baseMaterial: { // 构建表单基础参数
        keys: ['name', 'phone', 'identity_type', 'identity_number', 'to_visitor_name', 'to_visit_address', 'visit_description'],
        names: ['访客姓名', '访客手机号', '证件类型', '证件号码', '被访人姓名', '被访人地址', '来访原因']
      },
      certificates_type: certificates.type,
      isClearPreviewImg: false, // 是否清除预览图片
      face_file_id: -1, // 照片id
      visit_start_time: new Date(), // 来访开始时间
      visit_end_time: dayjs().add(12, 'hour').toDate(), // 来访结束时间
      Devices: [],
      isLoading: false,
      device_ids: []
    }
  },

  mounted () {
    this.constructForm()
  },

  components: {
    takePhoto
  },

  props: {
    value: { // 控制弹窗是否显示
      type: Boolean
    },
    homeId: [Number, String], // 房源id
    status: { // 0 => 新增， 1 => 查看, 2 => 编辑
      type: Number,
      default: 0
    },
    form: {
      type: Object,
      default: () => {}
    }
  },

  computed: {
    isShowModal: {
      get () {
        return this.value
      },
      set (value) {
        this.$emit('input', value)
      }
    },

    isShowbtn () { // 查看时不展示提交按钮
      return this.status !== 1
    },

    isShowPhoto () { // 查看和编辑的情况
      return this.status === 0
    },

    title () {
      return ['新增', '查看', '编辑'][this.status] + '访客'
    },

    /**
        * 公区设备
        */
    publicDevice () {
      return this.Devices.filter((device) => device.is_public)
    },

    /**
        * 单元门设备
        */
    privateDevice () {
      return this.Devices.filter((device) => !device.is_public)
    }
  },

  watch: {
    form (value) {
      if (Object.keys(value).length > 0) {
        this.constructForm(true)
      }
    },

    isShowModal (value) {
      if (!value) { // 重置预览图片
        this.isClearPreviewImg = true
      } else {
        this.isClearPreviewImg = false
      }

      if (this.status === 0 && value) { // 新增访客弹窗打开的时候获取门禁列表
        this.getAccessControllList()
      }
    }
  },

  methods: {
    /**
        *  获取门禁列表
        */
    async getAccessControllList () {
      this.isLoading = true
      try {
        this.Devices = await http.fetch(this, api.home_face_access, [this.homeId])

        this.device_ids = this.Devices.map((device) => (device.id))
      } catch (err) {
        console.log('err', err)
      } finally {
        this.isLoading = false
      }
    },

    typeChange (type) { // 证件类型修改修改校验类型
      this.$set(this.formRules, 'identity_number', type === 1 ? {
        required: true,
        validator: validate.validIDCard
      } : { required: true })
    },

    cancel () {
      this.reset()
      this.isShowModal = false
    },

    ok: debounce(function () { // 添加访客并且下发门禁授权
      if (!this.homeId) {
        this.$Message.error('房源id获取失败!')
        return
      }
      this.status === 0 ? this.createVistor() : this.editVistor()
    }),

    /**
        * 添加访客
        */
    createVistor () {
      this.$refs['form'].validate(async (valid) => {
        if (!valid) {
          this.$Message.error('请完整填写表单数据')
          return
        }

        if (this.face_file_id === -1) {
          this.$Message.error('您还没拍照')
          return
        }

        const params = {
          ...this.formData,
          visit_start_time: new Date(this.visit_start_time).valueOf(),
          visit_end_time: new Date(this.visit_end_time).valueOf(),
          face_file_id: this.face_file_id
        }

        try {
          const { visitor_id } = await http.fetch(this, api.add_visitor_record, [this.homeId], params)
          this.$Message.success('访客信息添加成功')

          this.$store.commit('refresh_vistor', Math.random()) // 刷新访客列表

          if (this.device_ids.length) { // 有门禁或者选择了门禁
            await this.authorize(visitor_id)
            this.$Message.success('门禁授权指令下发成功, 请去门禁授权列表里面检查相应的授权状态')
          }
          this.cancel()
        } catch (error) {
          console.log('error', error)
        }
      })
    },

    /**
        * 访客下发授权
        */
    async authorize (relation_id) {
      const params = {
        auth_start_time: new Date(this.visit_start_time).valueOf(),
        auth_end_time: new Date(this.visit_end_time).valueOf(),
        device_ids: this.device_ids,
        face_file_id: this.face_file_id,
        relation_role: 3,
        relation_id,
        description: this.formData.visit_description
      }

      return await http.fetch(this, api.face_access_add, [this.homeId], params)
    },

    /**
        * 编辑访客
        */
    editVistor () {
      this.$refs['form'].validate(async (valid) => {
        if (!valid) {
          this.$Message.error('请完整填写表单数据')
          return
        }

        const { to_visitor_name, to_visit_address, visit_description } = this.formData
        const params = {
          to_visitor_name,
          to_visit_address,
          visit_description
        }

        try {
          await http.fetch(this, api.edit_visitor_record, [this.homeId, this.form.id], params)
          this.cancel()
          this.$emit('refresh')
          this.$Message.success('访客信息修改成功')
        } catch (error) {
          console.log('error', error)
        }
      })
    },

    reset () {
      this.$refs['form'].resetFields()
      this.$set(this.formData, 'identity_type', 1)
      this.device_ids = []
      this.Devices = []
      this.face_file_id = -1
    },

    /**
        * 构造表单初始化数据和校验规则
        */
    constructForm (hasData = false) {
      const { keys } = this.baseMaterial

      const data = {}
      const rule = {}
      const isDisable = {}

      keys.map((key, index) => {
        if (hasData) { // 编辑和查看访客
          data[key] = this.form[key]
          isDisable[key] = !((this.status === 2 && ['to_visitor_name', 'to_visit_address', 'visit_description'].includes(key)))
        } else { // 新增访客
          data[key] = key === 'identity_type' ? 1 : ''
          isDisable[key] = false
        }

        rule[key] = this.constructRule(key, (hasData && key === 'identity_number' && this.form['identity_type'] === 2))
      })

      this.formRules = rule // 构造表单规则
      this.formData = data // 构造表单数据
      this.isDisable = isDisable // 表单是否禁止编辑

      if (!hasData) {
        setTimeout(() => { // 默认清除表单验证效果
          this.reset()
        }, 100)
      } else {
        this.visit_start_time = new Date(this.form['visit_time_range'][0])
        this.visit_end_time = new Date(this.form['visit_time_range'][1])
      }
    },

    /**
        * 根据 key 生成规则
        */
    constructRule (key, flag) {
      if (key === 'phone') { // 电话规则
        return {
          required: true,
          validator: validate.validPhone
        }
      }

      if (key === 'identity_number') { // 身份证号码
        return flag ? {
          required: true
        } : {
          required: true,
          validator: validate.validIDCard
        }
      }

      if (key === 'to_visit_address' || key === 'visit_description') {
        return {
          required: true,
          max: 140
        }
      }

      return {
        required: true
      }
    }
  }
}
</script>
<style lang='less'>
.center {
    text-align: center;
}

.authorize {
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;

    .ivu-form-item {
        width: 100%;
    }
}

.loadSpin {
    height: 80px;
}
</style>